package cn.cxy.simpletimepicker.widget

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import cn.cxy.simpletimepicker.R
import kotlinx.android.synthetic.main.view_cust_timepicker.view.*
import java.util.*

class CustTimePicker(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) {
    private var mSelectedDay: ListItem? = null
    private var mSelectedInterval: ListItem? = null
    private var mSelectedHour: ListItem? = null
    private var mOnTimeChangedListener: OnTimeChangedListener? = null
    private var isTodaySelected = false
    private var today = 0
    private var tomorrow = 1
    private var unknown = 2
    private var intervals = ArrayList<IntervalInfo>()

    init {
        LayoutInflater.from(context).inflate(R.layout.view_cust_timepicker, this, true)
        initData()
    }

    private fun initData() {
        isTodaySelected = false
        intervals.clear()
        intervals.add(IntervalInfo(0, "凌晨", 0, 5))
        intervals.add(IntervalInfo(1, "上午", 6, 11))
        intervals.add(IntervalInfo(2, "下午", 12, 17))
        intervals.add(IntervalInfo(3, "晚上", 18, 23))
        initDayTimePicker()
    }

    /**
     * 重新初始化界面
     */
    fun reset() {
        initData()
    }

    private fun initDayTimePicker() {
        val dayList = getDayData()
        dayPickView.setData(dayList, TimePickerView.viewTypeMinute)
        dayPickView.setOnSelectListener { item ->
            Log.v("TimePicker", "dayPickView selected")
            if (item != mSelectedDay) {
                mSelectedDay = item
                isTodaySelected = item.id == today
                if (mOnTimeChangedListener != null) {
                    mOnTimeChangedListener?.onTimeChanged(this, Date())
                }
                if (item.id == unknown) {
                    intervalPickView.visibility = View.INVISIBLE
                    hourPickView.visibility = View.INVISIBLE
                } else {
                    intervalPickView.visibility = View.VISIBLE
                    hourPickView.visibility = View.VISIBLE
                    resetIntervalList()
                }
            }

        }
        dayPickView.setSelectedByIndex(0, true)
    }

    private fun initIntervalPickView() {
        val intervalList = getIntervalData()
        intervalPickView.setData(intervalList, TimePickerView.viewTypeHour)
        intervalPickView.setOnSelectListener { item ->
            Log.v("TimePicker", "intervalPickView selected")
            mSelectedInterval = item
            if (mOnTimeChangedListener != null) {
                mOnTimeChangedListener?.onTimeChanged(
                    this,
                    Date()
                )
            }
            resetHourList()
            selectHourByInterval(false)
        }
        intervalPickView.setSelectedByIndex(0, true)
    }


    private fun initHourPickView() {
        val hourList = getHourData()
        hourPickView.setData(hourList, TimePickerView.viewTypeHour)
        hourPickView.setOnSelectListener { item ->
            Log.v("TimePicker", "hourPickView selected")
            mSelectedHour = item
            if (mOnTimeChangedListener != null) {
                mOnTimeChangedListener?.onTimeChanged(
                    this,
                    Date()
                )
            }
            selectIntervalByHour()
        }
    }

    private fun selectIntervalByHour() {
        intervalPickView.setSelectedById(getIntervalForHour(), false)
    }

    private fun getIntervalForHour(): Int {
        var intervalId = 0
        mSelectedHour?.let {
            intervals.forEach { interval ->
                if (it.IntValue >= interval.startHour && it.IntValue <= interval.endHour) {
                    intervalId = interval.id
                }
            }
        }

        return intervalId
    }

    private fun selectHourByInterval(notifyListeners: Boolean) {
        mSelectedInterval?.let {
            hourPickView.setSelectedByValue(it.IntValue, notifyListeners)
            mSelectedHour = hourPickView.selectedItem
        }
    }

    private fun resetIntervalList() {
        initIntervalPickView()
    }

    private fun resetHourList() {
        initHourPickView()
    }

    private fun getDayData(): ArrayList<ListItem> {
        val dayList = ArrayList<ListItem>()

        val cal = Calendar.getInstance()
        cal.set(Calendar.HOUR_OF_DAY, 23)
        cal.set(Calendar.MINUTE, 0)
        cal.set(Calendar.SECOND, 0)
        val lateOfToday = cal.time

        dayList.apply {
            if (Date().before(lateOfToday)) {
                add(ListItem(today, today, "今天"))
            }
            add(ListItem(tomorrow, tomorrow, "明天"))
            add(ListItem(unknown, unknown, "不知道卸货时间"))
        }
        return dayList
    }

    private fun getIntervalData(): ArrayList<ListItem> {
        val intervalList = ArrayList<ListItem>()

        intervalList.apply {
            if (isTodaySelected) {
                intervals.forEach {
                    val nextHour = getNextHour()
                    if (nextHour <= it.endHour) {
                        add(it.toListItem())
                    }
                }

            } else {
                intervals.forEach { add(it.toListItem()) }
            }
        }
        return intervalList
    }


    private fun getHourData(): ArrayList<ListItem> {
        val hourList = ArrayList<ListItem>()
        if (isTodaySelected) {
            getHours(getNextHour(), hourList)
        } else {
            getHours(0, hourList)
        }
        return hourList
    }

    private fun getHours(startHour: Int, hourList: ArrayList<ListItem>) {
        var str: String
        for (i in startHour..23) {
            str = if (i < 10) {
                "0$i:00"
            } else {
                "$i:00"
            }
            hourList.add(ListItem(i, i, str))
        }
    }

    fun getSelectedTime(): Date? {
        var selectedTime: Date? = null
        val calendar = Calendar.getInstance()
        calendar.set(Calendar.MINUTE, 0)
        calendar.set(Calendar.SECOND, 0)

        mSelectedDay?.let {
            calendar.set(Calendar.HOUR_OF_DAY, mSelectedHour?.IntValue ?: 0)
            if (it.id == today) {
                selectedTime = calendar.time
            } else if (it.id == tomorrow) {
                calendar.add(Calendar.DATE, 1)
                selectedTime = calendar.time
            }
        }
        return selectedTime
    }

    private fun getNextHour() = Calendar.getInstance().get(Calendar.HOUR_OF_DAY) + 1

    interface OnTimeChangedListener {
        fun onTimeChanged(myTimePicker: CustTimePicker?, date: Date)
    }
}